package com.wu.ssm.study.ioc;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by wzf on 2018/11/7/007.
 */
public class MyApplicationContext {

    //单实例
    private static Map<String, Object> single = new HashMap<>();
    //多实例
    private static Map<String, BeanXml> mult = new HashMap<>();

   /* static{
        List<BeanXml> beanList = getCofigXml();
        try {
            initBean(beanList);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }*/

    private  void initBean(List<BeanXml> beanList) {
        for (BeanXml b:beanList
             ) {
            mult.put(b.getName(),b);
        }

        for (BeanXml beanXml:beanList) {
            String beanName = beanXml.getName();
            String beanClass = beanXml.getClassName();
            String scope = beanXml.getScope();

            BeanXml bea = null;
            if(scope != null && "prototype".equals(scope)){
                bea = new BeanXml();
                bea.setName(beanName);
                bea.setClassName(beanClass);
                bea.setName(scope);
                for (Property property:beanXml.getProperties()
                ) {

                    Property pro = new Property();
                    String propName = property.getName();
                    String propValue = property.getValue();
                    pro.setName(propName);
                    if(propValue == null){
                        pro.setRef(property.getValue());
                    }else {
                        pro.setValue(propValue);
                    }
                    addProp(beanName,pro);
                }
            }
            else {
                //单例
                createSingleBean(beanXml);
            }
        }
    }


    public void setFeidPropVlue(Object obj,Field field, String propValue) throws IllegalAccessException {

        if("java.lang.Boolean".equals(field.getGenericType().getTypeName()) ){
            field.set(obj, Boolean.valueOf(propValue));
        }/*else if("java.lang.Character".equals(field.getGenericType().getTypeName()) ){
            field.setChar(obj, new Character());
        }*/else if("java.lang.Byte".equals(field.getGenericType().getTypeName()) ){
            field.set(obj, Byte.valueOf(propValue));
        }else if("java.lang.Short".equals(field.getGenericType().getTypeName()) ){
            field.set(obj, Short.valueOf(propValue));
        }else if("java.lang.Long".equals(field.getGenericType().getTypeName()) ){
            field.set(obj, Long.valueOf(propValue));
        }else if("java.lang.Integer".equals(field.getGenericType().getTypeName()) ){
            field.set(obj, Integer.valueOf(propValue));
        }else if("java.lang.Float".equals(field.getGenericType().getTypeName()) ){
            field.set(obj, Float.valueOf(propValue));
        }else if("java.lang.Double".equals(field.getGenericType().getTypeName()) ){
            field.set(obj, Double.valueOf(propValue));
        }else {
            field.set(obj, propValue);
        }
    }
    private static List<BeanXml> getCofigXml(){
        List<BeanXml> beanList = new ArrayList<>();

        BeanXml user = new BeanXml();
        user.setName("user");
        user.setClassName("com.wu.ssm.study.ioc.User");
        List<Property> properties = new ArrayList<>();
        Property pa = new Property();
        pa.setName("username");
        pa.setValue("张三");
        properties.add(pa);
        Property pa2 = new Property();
        pa2.setName("dept");
        pa2.setRef("dept");
        properties.add(pa2);
        user.setProperties(properties);
        beanList.add(user);


        BeanXml dept = new BeanXml();
        //dept.setScope("prototype");
        dept.setName("dept");
        dept.setClassName("com.wu.ssm.study.ioc.Dept");
        List<Property> propertieb = new ArrayList<>();
        Property pb1 = new Property();
        pb1.setName("deptName");
        pb1.setValue("财务部门");
        Property pb2 = new Property();
        pb2.setName("id");
        pb2.setValue("1");
        propertieb.add(pb1);
        propertieb.add(pb2);
        dept.setProperties(propertieb);
        beanList.add(dept);

        return beanList;
    }
    public MyApplicationContext() {
        System.out.println("加载配置文件");
        List<BeanXml> beanList = getCofigXml();
            initBean(beanList);
    }

    /**
     *
     * create by wuzhifeng
     * date: 2018/11/7/007
     */
    public Object getBean(String beanName) {
        Object obj = single.get(beanName);
        if(obj == null){
            BeanXml b = mult.get(beanName);
            if(b == null){
                System.out.println("没有bean");
                return null;
            }
            return createSingleBean(b);
        }

        return obj;
    }

    public Object createSingleBean(BeanXml beanXml){

        try {
            Class clazz = Class.forName(beanXml.getClassName());
            Object obj = clazz.newInstance();
            for (Property property:beanXml.getProperties()
            ) {
                String propName = property.getName();
                String propValue = property.getValue();
                //
                Field field = clazz.getDeclaredField(propName);
                field.setAccessible(true);
                if(propValue == null){
                    field.set(obj,getBean(property.getRef()));
                }else {
                    setFeidPropVlue(obj, field, propValue);
                }
            }
            single.put(beanXml.getName(),obj);
            return obj;

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        return null;
    }
    private static void addProp(String beanName, Property property){}


}
